/* ------------------------------------------------------------
 *  Bunny project - TacTile communication
 *
 * ------------------------------------------------------------ 
 */
 
import tacTile.net.*;

final float OBJECT_1_DISTANCE 	= 80.0;		// distance between 2 LEDs on food dish 1
final float FONT_SIZE_LL		= 40.0;

class TacTileTracker
{
	PFont labelFont;
	TouchAPI api;
	ArrayList touchList;
	ArrayList<IVector> points;
	HashMap< Integer, IVector> objects;
	
	// variables to calculate mapping
	float w, h;
	float half_wCrop, half_hCrop;
	float hRatio, wRatio;
	
	TacTileTracker()
	{
		api = null;
		touchList = null;
		points = new ArrayList<IVector>();
		objects = new HashMap< Integer, IVector >();
		
		labelFont = createFont( "HelveticaBold", FONT_SIZE_LL );
		
		// calculate mapping between TacTile coordinates and scaled bunny space coordinates
		w = (float) environment.getMapWidth() * environment.getScale();
		h = (float) environment.getMapHeight() * environment.getScale();
		
		half_wCrop = ((float) TACTILE_WIDTH - w) / 2.0;
		half_hCrop = ((float) TACTILE_HEIGHT - h) / 2.0;
		
		wRatio = TACTILE_WIDTH / w;
		hRatio = TACTILE_HEIGHT / h;		
	}
	
	void connect(PApplet applet)
	{
		api = new TouchAPI(applet, UDP_PORT, TACTILE_PORT, TACTILE_HOST);
		api.log_on(true);
	}
	
	IVector mapTacTile(IVector v)
	{
		float x = (v.x - half_wCrop);
		float y = (v.y - half_hCrop);
		
		return new IVector(
			round(x),
			round(y)
		);
	}
	
	void refresh()
	{
		touchList = api.getManagedList();
		points.clear();
		
		// loop through items
		for (int i = 0; i < touchList.size(); i++)
		{
			Touches curTouch = (Touches) touchList.get(i);
			if ( curTouch != null )
			{
				IVector v = new IVector(
					round( curTouch.getXPos() * (float) TACTILE_WIDTH ),
					TACTILE_HEIGHT - round( curTouch.getYPos() * (float) TACTILE_HEIGHT )
				);
				points.add(v);
			}	
		}
		
		// clear object list
		objects.clear();
		
		// identify first object (two dots close to each others)
		boolean found = false;
		for (int i = 1; i < points.size() && !found; i++)
		{
			for (int j = 0; j < i && !found; j++)
			{
				IVector p1 = points.get(i);
				IVector p2 = points.get(j);
				float d = p1.distance(p2);
				if ( d < OBJECT_1_DISTANCE )
				{
					IVector o = new IVector(
						(p1.x + p2.x) / 2,
						(p1.y + p2.y) / 2
					);
					
					objects.put( 0, mapTacTile(o) );
					
					// mark p1 and p2 to be removed from consideration
					p1.cost = 0;
					p2.cost = 0;
					found = true;
				}
			}
		}
		
		// look at the rest of obejcts
		int oCounter = 1;
		for (int i = 0; i < points.size(); i++)
		{
			IVector p = points.get(i);
			if (p.cost == 0)
			{
				// ignore
				continue;
			}
			else
			{
				objects.put( oCounter, mapTacTile(p) );
				oCounter++;
			}
		}
	}
	
	HashMap<Integer, IVector> getTracked()
	{
		return objects;
	}
	
	void draw()
	{
		// draw the location of objects if any
		pushStyle();
		pushMatrix();
		resetMatrix();
		{	
			
			Iterator it = objects.entrySet().iterator();
			while (it.hasNext()) 
			{
				Map.Entry pairs = (Map.Entry) it.next();
				
				int id = (Integer) pairs.getKey();
				IVector p = (IVector) pairs.getValue();
		
				String txt = "" + id;
				
				// draw background
				rectMode(CENTER);
				noStroke();
				fill( #FFAC86 );
				
				rect( p.x, p.y, textWidth(txt) + 10, FONT_SIZE_LL + 10 );
					
						
				textFont(labelFont);
				textAlign(CENTER, CENTER);
				stroke(0);
				fill(0);
		
				// draw label
				text( txt, p.x, p.y );
			}
		}
		popMatrix();
		popStyle();
	}
}

